<?php

// **************************************************************
// | Name: 星空框架  银联支付模块
// **************************************************************
// | Version: V5.0
// **************************************************************
// | Author: xkyinzhe <zhonghuaxinxing@sina.cn>
// **************************************************************
// | City: 青岛
// **************************************************************
// | Time: 2021-10-22 10:36
// **************************************************************
declare(strict_types=1);

namespace app\common\controller;

use app\common\common\BaseController;
use app\common\model\Order as OrderModel;
use app\common\model\SubOrder as SubOrderModel;
use app\common\model\GoodsOrder as GoodsOrderModel;
use app\common\model\RefundOrder as RefundOrderModel;
use app\common\services\OrderServices;
use app\common\services\UserServices;
use app\common\services\FinanceServices;
use think\facade\Db;

/**
 * @xk 银联支付
 */
class Unionpay extends BaseController
{

  public function houtai(){
    // 后台下单模式
    //   $post_data = [];
    //   $post_data['requestTimestamp'] = date('Y-m-d H:i:s');
    //   $post_data['merOrderId'] = $pay_order_sn; // 订单支付编号
    //   $cancel_time = (int)config('web_config.cancel_hour')*3600;
    //   $post_data['expireTime'] = date('Y-m-d H:i:s', time()+$cancel_time); // 一小时后自动关闭订单 重新发起
    //   $post_data['mid'] = config('pay_config.unionpay.mid');
    //   $post_data['tid'] = config('pay_config.unionpay.tid');
    //   $post_data['instMid'] = config('pay_config.unionpay.instMid');
    //   $post_data['tradeType'] = 'JSAPI';
    //   $post_data['orderDesc'] = '用户使用微信支付商品';
    //   $post_data['totalAmount'] = $need_pay;
    //   $post_data['notifyUrl'] = $notifyUrl;
    //   $post_data['returnUrl'] = $returnUrl;
    //   $post_data['subOpenId'] = $openid;
    //   $Authorization = self::getUnionPayAccesstoken($post_data);
    //   // $url = 'https://api-mop.chinaums.com/v1/netpay/wx/unified-order'; // 后台下单 正式环境
    //   $url = 'https://test-api-open.chinaums.com/v1/netpay/wx/unified-order'; // 后台下单 微信支付
    //   $headers = [
    //   "Content-type: application/json;charset='utf-8'",
    //   "Authorization:".$Authorization
    // ];
    //   $result = self::https_request($url, json_encode($post_data), $headers);
    //   $resultData = json_decode($result, true);
    //   switch ($resultData['errCode']) {
    //     case 'SUCCESS':
    //       $jsApiObj=$resultData['jsPayRequest'];
    //       return $jsApiObj;
    //       break;
    //     default:
    //       throw new \think\Exception($resultData['errMsg'], 404);
    //       break;
    //   }
  }


    /**
     * @xk 银联支付
     *
     * @method wechatPay
     * @param  [type]     $order_data                [description]
     * @return [type]     [description]
     * @Time   2021-10-22
     * @City   青岛
     * @Author xkyinzhe   <zhonghuaxinxing@sina.cn>
     */
    public static function wecahtPay($order_data=[], $be_from='H5')
    {
        $orderModel = new OrderModel();
        $post_data = [];
        if (!$order_data) {
            throw new \think\Exception("支付订单错误", 404);
        }
        $order_sn = $order_data['order_sn'];
        $need_pay = $order_data['need_pay']*100; // 组合支付金额
        // $pay_order_sn = $orderModel->getCodeNo(config('web_config.msgSrcId').$order_sn, 30, 1);
        $pay_order_sn = config('web_config.msgSrcId').$order_sn;
        $orderModel->where([['order_sn','=',$order_sn]])->find()->save(['pay_order_sn'=>$pay_order_sn]);
        $notifyUrl = 'https://'.$_SERVER['HTTP_HOST'].'/'.config('web_config.orderPayBack');
        $returnUrl = 'https://'.$_SERVER['HTTP_HOST'].'/#/pages/pay_success/pay_success?act=all&order_sn='.$order_sn;
        switch ($be_from) {
          case 'H5':
            return self::doWechatPay($pay_order_sn, $need_pay, $notifyUrl, $returnUrl);
            break;
          case 'wxapp':
            $openid = $order_data['wechat_app_openId'];
            return self::doWechatAppPay($pay_order_sn, $need_pay, $openid, $notifyUrl, $returnUrl);
            break;
          case 'app':
            $notifyUrl = 'https://'.$_SERVER['HTTP_HOST'].'/'.config('wechat_config.orderPayBack');
            return self::doAppPay($pay_order_sn, $need_pay, $notifyUrl);
            break;
        }
    }
    /**
     * @xk 子订单支付
     *
     * @method subOrderPay
     * @param  array       $order_data                [description]
     * @return [type]      [description]
     * @Time   2021-10-23
     * @City   青岛
     * @Author xkyinzhe    <zhonghuaxinxing@sina.cn>
     */
    public static function subOrderPay($order_data = [], $be_from='H5')
    {
        $subOrderModel = new SubOrderModel();
        $post_data = [];
        if (!$order_data) {
            throw new \think\Exception("支付订单错误", 404);
        }
        $sub_order_sn = $order_data['sub_order_sn'];
        $need_pay = $order_data['need_pay']*100; // 组合支付金额
        // $pay_order_sn = $subOrderModel->getCodeNo(config('web_config.msgSrcId').$sub_order_sn, 30, 1);
        $pay_order_sn = config('web_config.msgSrcId').$sub_order_sn;
        $subOrderModel->where([['sub_order_sn','=',$sub_order_sn]])->find()->save(['pay_order_sn'=>$pay_order_sn]);
        $notifyUrl = 'https://'.$_SERVER['HTTP_HOST'].'/'.config('web_config.subOrderPayBack');
        $returnUrl = 'https://'.$_SERVER['HTTP_HOST'].'/#/pages/pay_success/pay_success?act=sub&order_sn='.$sub_order_sn;
        switch ($be_from) {
          case 'H5':
            return self::doWechatPay($pay_order_sn, $need_pay, $notifyUrl, $returnUrl);
            break;
          case 'wxapp':
            $openid = $order_data['wechat_app_openId'];
            return self::doWechatAppPay($pay_order_sn, $need_pay, $openid, $notifyUrl, $returnUrl);
            break;
          case 'app':
            $notifyUrl = 'https://'.$_SERVER['HTTP_HOST'].'/'.config('wechat_config.orderPayBack');
            return self::doAppPay($pay_order_sn, $need_pay, $notifyUrl);
            break;
        }
    }
    /**
     * @xk 组合支付参数等信息
     *
     * @method doWechatPay
     * @param  [type]      $pay_order_sn              [description]
     * @param  [type]      $need_pay                  [description]
     * @param  [type]      $notifyUrl                 [description]
     * @param  [type]      $returnUrl                 [description]
     * @return [type]      [description]
     * @Time   2021-10-23
     * @City   青岛
     * @Author xkyinzhe    <zhonghuaxinxing@sina.cn>
     */
    public static function doWechatPay($pay_order_sn, $need_pay, $notifyUrl, $returnUrl)
    {
        $post_data['msgSrc'] = config('pay_config.unionpay.msgSrc');
        $post_data['msgType'] = 'WXPay.jsPay';
        $post_data['requestTimestamp'] = date('Y-m-d H:i:s');
        $cancel_time = (int)config('web_config.cancel_hour')*3600;
        $post_data['expireTime'] = date('Y-m-d H:i:s', time()+$cancel_time); // 一小时后自动关闭订单 重新发起
        $post_data['merOrderId'] = $pay_order_sn; // 订单支付编号
        $post_data['mid'] = config('pay_config.unionpay.mid');
        $post_data['tid'] = config('pay_config.unionpay.tid');
        $post_data['instMid'] = config('pay_config.unionpay.instMid');
        $post_data['orderDesc'] = '用户使用微信支付商品';
        $post_data['totalAmount'] = $need_pay;
        $post_data['notifyUrl'] = $notifyUrl;
        $post_data['returnUrl'] = $returnUrl;
        $post_data['signType'] = 'SHA256';
        // $post_data['subOpenId'] = '';
        // $post_data['subAppId'] = config('web_config.appid');
        $post_data['sign'] =self::makeSign($post_data, config('pay_config.unionpay.unionpayscript'));
        // $url = 'https://qr.chinaums.com/netpay-portal/webpay/pay.do?'.self::signTemp($post_data);
        $url = 'https://test-api-open.chinaums.com/v1/netpay/webpay/pay';
        return $url;
    }
    /**
     * @xk 小程序支付调用
     *
     * @method doWechatAppPay
     * @param  [type]         $pay_order_sn              [description]
     * @param  [type]         $need_pay                  [description]
     * @param  [type]         $openid                    [description]
     * @param  [type]         $notifyUrl                 [description]
     * @param  [type]         $returnUrl                 [description]
     * @return [type]         [description]
     * @Time   2021-12-10
     * @City   青岛
     * @Author xkyinzhe       <zhonghuaxinxing@sina.cn>
     */
    public static function doWechatAppPay($pay_order_sn, $need_pay, $openid, $notifyUrl, $returnUrl)
    {
        $post_data['msgSrc'] = config('pay_config.unionpay.msgSrc');
        $post_data['msgType'] = 'WXPay.jsPay';
        $post_data['requestTimestamp'] = date('Y-m-d H:i:s');
        $cancel_time = (int)config('web_config.cancel_hour')*3600;
        $post_data['expireTime'] = date('Y-m-d H:i:s', time()+$cancel_time); // 一小时后自动关闭订单 重新发起
        $post_data['merOrderId'] = $pay_order_sn; // 订单支付编号
        $post_data['mid'] = config('pay_config.unionpay.mid');
        $post_data['tid'] = config('pay_config.unionpay.tid');
        // $post_data['instMid'] = config('web_config.instMid');
        $post_data['instMid'] = 'MINIDEFAULT';
        $post_data['orderDesc'] = '用户使用微信支付商品';
        $post_data['totalAmount'] = $need_pay;
        $post_data['notifyUrl'] = $notifyUrl;
        $post_data['subOpenId'] = $openid;
        $post_data['signType'] = 'SHA256';
        $post_data['tradeType'] = 'MINI';
        $post_data['subAppId'] = config('core_config.wechat_applet_config.app_id');
        $post_data['sign'] =self::makeSign($post_data, config('pay_config.unionpay.unionpayscript'));
        $url = "https://qr.chinaums.com/netpay-route-server/api/"; // 测试环境
        $res = https_request($url, json_encode($post_data));
        $result = json_decode($res, true);
        // var_dump($result); die();
        if ($result['errCode'] != 'SUCCESS' || $result['status'] != 'WAIT_BUYER_PAY') {
            throw new \think\Exception($result['errMsg'], 404);
        }
        $pay_info = [];
        $pay_info = $result['miniPayRequest'];
        return $pay_info;
    }
    /**
     * @xk 执行app支付
     * @method                                 doAppPay
     * @param                                  [type] $pay_order_sn  [description]
     * @param                                  [type] $need_pay  [description]
     * @param                                  [type] $notifyUrl  [description]
     * @return                                 [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                        <zhonghuaxinxing@sina.cn>
     * @City：                                  青岛
     * @Time：2022-02-10Tfalse14:false26:09+080
     */
    public static function doAppPay($pay_order_sn, $need_pay, $notifyUrl)
    {
        $push['appid'] = config('wechat_config.wechat_app_id');
        $push['body'] = '用户购买商品进行微信支付';
        $push['mch_id'] = config('wechat_config.wechat_mch_id');
        $push['nonce_str'] = self::nocestr();
        $push['out_trade_no'] = $pay_order_sn;
        $push['notify_url'] = $notifyUrl;
        $push['sign_type'] = 'MD5';
        $push['spbill_create_ip'] = $_SERVER['REMOTE_ADDR']; //终端的ip
        $push['total_fee'] = $need_pay; //总金额 最低为一块钱 必须是整数
        $push['trade_type'] = 'APP';
        $push['sign'] = self::wechatMakeSign($push, config('wechat_config.wecaht_mch_script')); //签名
        $post_xml = self::toXml($push);
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $xml = https_request($url, $post_xml); //调用统一下单接口
        // 处理返回数据
        $array = self::getxml($xml); //全要大写
        if ('SUCCESS' != $array['return_code']) {
            throw new \think\Exception($array['return_msg'], 404);
        }
        if ('SUCCESS' != $array['result_code']) {
            throw new \think\Exception($array['err_code_des'], 404);
        }
        $prepay_id = $array['prepay_id'];
        $timeStamp = time();
        $jsApiObj['appid'] = config('core_config.wechat_app_config.app_id');
        $jsApiObj['noncestr'] = self::nocestr();
        $jsApiObj['package'] = 'Sign=WXPay';
        $jsApiObj['partnerid'] = config('wechat_config.wechat_mch_id');
        $jsApiObj['prepayid'] = $prepay_id;
        $jsApiObj['timestamp'] = "$timeStamp";
        $jsApiObj['sign'] = self::wechatMakeSign($jsApiObj, config('wechat_config.wecaht_mch_script'));
        return $jsApiObj;
    }
    /**
     * @xk 子订单支付回调
     *
     * @method SubOrderPayBack
     * @Time   2021-10-23
     * @City   青岛
     * @Author xkyinzhe        <zhonghuaxinxing@sina.cn>
     */
    public static function SubOrderPayBack()
    {
        Db::startTrans();
        $param = request()->param();
        $path = 'unionpay/pay/subOrder/';
        $pay_order_sn = $param['merOrderId']; // 发起请求的id
        $content = "===================【".$pay_order_sn."】支付回调请求开始==========================\n";
        try {
            if ($param['status'] != 'TRADE_SUCCESS') {
                switch ($param['status']) {
                  case 'NEW_ORDER':
                    throw new \think\Exception("新订单交易", 404);
                    break;
                  case 'UNKNOWN':
                    throw new \think\Exception("交易状态不明确", 404);
                    break;
                  case 'TRADE_CLOSED':
                    throw new \think\Exception("交易关闭", 404);
                    break;
                  case 'WAIT_BUYER_PAY':
                    throw new \think\Exception("等待卖家付款", 404);
                    break;
                  case 'TRADE_REFUND':
                    throw new \think\Exception("订单进入退货流程", 404);
                    break;
                }
            }
            $subOrderModel = new SubOrderModel();
            $orderServices = new OrderServices();
            $financeServices = new FinanceServices();
            $order_info = $subOrderModel->where([['pay_order_sn','=',$pay_order_sn]])->field('`sub_order_sn`,`user_sn`,`status`,`pay_status`,`shipping_type`,`sub_order_id`')->find();
            if (!$order_info) {
                throw new \think\Exception("订单不存在", 404);
            }
            if ($order_info['pay_status'] != 0) {
                throw new \think\Exception("订单状态错误", 404);
            }
            $order_data = [];
            $shipping_type = $order_info['shipping_type'];
            $order_data['status'] = 1;
            if ($shipping_type == 2) {
                $order_data['status'] = 2; //
                $order_data['delivery_time'] = date('Y-m-d H:i:s'); // 自提订单记录发货时间
            }
            $order_data['pay_status'] = 1;
            $order_data['sub_order_id'] = $order_info['sub_order_id'];
            $order_data['pay_time'] = $param['payTime']; // 支付时间
            $order_data['pay_type'] = 1;
            $order_data['pay_price'] = $param['receiptAmount']/100; // 支付金额
            $order_data['pay_code'] = $param['targetOrderId']; // 支付流水号
            $order_res = $subOrderModel->find($order_info['sub_order_id'])->save($order_data);
            $orderServices->syncOrderGoodsStatus($order_info['sub_order_sn']);
            $finance_data = [];
            $finance_data['relation_num'] = $order_info['sub_order_sn'];
            $finance_data['relation_user_num'] = $order_info['user_sn'];
            $finance_data['entry'] = 1;
            $finance_data['money'] = $order_data['pay_price'];
            $finance_data['content'] = '用户购买商品进行支付';
            $finance_data['pay_type'] = 1;
            $finance_data['act'] = 2;
            $financeServices->syncFinance($finance_data);
            echo "SUCCESS";
            $content .="========================处理成功============================";
            Db::commit();
        } catch (\Exception $e) {
            $content .="===========================".$e->getMessage()."==========================\n";
            Db::rollback();
        };
        createLog($path, $content);
    }
    /**
     * @xk 订单支付回调
     *
     * @method orderPayBack
     * @return [type]       [description]
     * @Time   2021-10-23
     * @City   青岛
     * @Author xkyinzhe     <zhonghuaxinxing@sina.cn>
     */
    public static function orderPayBack()
    {
        Db::startTrans();
        $param = request()->param();
        $path = 'unionpay/pay/order/';
        $pay_order_sn = $param['merOrderId']; // 发起请求的id
        $content = "=============【".$pay_order_sn."】支付回调请求开始==========================\n";
        try {
            if ($param['status'] != 'TRADE_SUCCESS') {
                switch ($param['status']) {
                  case 'NEW_ORDER':
                    throw new \think\Exception("新订单交易", 404);
                    break;
                  case 'UNKNOWN':
                    throw new \think\Exception("交易状态不明确", 404);
                    break;
                  case 'TRADE_CLOSED':
                    throw new \think\Exception("交易关闭", 404);
                    break;
                  case 'WAIT_BUYER_PAY':
                    throw new \think\Exception("等待卖家付款", 404);
                    break;
                  case 'TRADE_REFUND':
                    throw new \think\Exception("订单进入退货流程", 404);
                    break;
                }
            }
            $orderModel = new OrderModel();
            $orderServices = new OrderServices();
            $financeServices = new FinanceServices();
            $order_info = $orderModel->where([['pay_order_sn','=',$pay_order_sn]])->field('`order_sn`,`user_sn`,`status`,`pay_status`,`shipping_type`,`order_id`')->find();
            if (!$order_info) {
                throw new \think\Exception("订单不存在", 404);
            }
            if ($order_info['pay_status'] != 0) {
                throw new \think\Exception("订单状态错误", 404);
            }
            $order_data = [];
            $shipping_type = $order_info['shipping_type'];
            $order_data['status'] = 1;
            if ($shipping_type == 2) {
                $order_data['status'] = 2; //
                $order_data['delivery_time'] = date('Y-m-d H:i:s'); // 自提订单记录发货时间
            }
            $order_data['pay_status'] = 1;
            $order_data['order_id'] = $order_info['order_id'];
            $order_data['pay_time'] = $param['payTime']; // 支付时间
            $order_data['pay_type'] = 1;
            $order_data['pay_price'] = $param['receiptAmount']/100; // 支付金额
            $order_data['pay_code'] = $param['targetOrderId']; // 支付流水号
            $order_res = $orderModel->find($order_info['order_id'])->save($order_data);
            $orderServices->syncSubOrderPay($order_info['order_sn']);
            $finance_data = [];
            $finance_data['relation_num'] = $order_info['order_sn'];
            $finance_data['relation_user_num'] = $order_info['user_sn'];
            $finance_data['entry'] = 1;
            $finance_data['money'] = $order_data['pay_price'];
            $finance_data['content'] = '用户购买商品进行支付';
            $finance_data['pay_type'] = 1;
            $finance_data['act'] = 1;
            $financeServices->syncFinance($finance_data);
            $content .="========================处理成功============================";
            echo "SUCCESS";
            Db::commit();
        } catch (\Exception $e) {
            $content .="===========================".$e->getMessage()."==========================\n";
            Db::rollback();
        }
        createLog($path, $content);
    }
    /**
     * @xk 微信支付订单回调
     * @method                                      wechatOrderPayBack
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-02-10Tfalse14:false56:false36+080
     */
    public static function wechatOrderPayBack()
    {
        $orderModel = new OrderModel();
        $orderServices = new OrderServices();
        $financeServices = new FinanceServices();
        Db::startTrans();
        $path = 'wechatPay/orderPay/';
        $content = "---------------【接收订单回调】---------------------------\n";
        try {
            $result = file_get_contents('php://input');
            $data = self::getxml($result); //开始处理微信回调
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            if ('SUCCESS' != $data['result_code']) {
                throw new \think\Exception($result, 404);
            }
            $content .= '----------------------订单编号----'.$data['out_trade_no']."------------------------\n";
            $pay_order_sn = $data['out_trade_no'];
            $order_info = $orderModel->where([['pay_order_sn','=',$pay_order_sn]])->field('`order_sn`,`user_sn`,`status`,`pay_status`,`shipping_type`,`order_id`')->find();
            if (!$order_info) {
                throw new \think\Exception("订单不存在", 404);
            }
            if ($order_info['pay_status'] != 0) {
                throw new \think\Exception("订单状态错误", 404);
            }
            $order_data = [];
            $shipping_type = $order_info['shipping_type'];
            $order_data['status'] = 1;
            if ($shipping_type == 2) {
                $order_data['status'] = 2; //
              $order_data['delivery_time'] = date('Y-m-d H:i:s'); // 自提订单记录发货时间
            }
            $order_data['pay_status'] = 1;
            $order_data['order_id'] = $order_info['order_id'];
            $order_data['pay_time'] = date('Y-m-d H:i:s'); // 支付时间
            $order_data['pay_type'] = 5; // 原生微信支付
            $order_data['pay_price'] = $data['total_fee']/100; // 支付金额
            $order_data['pay_code'] = $data['transaction_id']; // 支付流水号
            $order_res = $orderModel->find($order_info['order_id'])->save($order_data);
            $orderServices->syncSubOrderPay($order_info['order_sn']);
            $finance_data = [];
            $finance_data['relation_num'] = $order_info['order_sn'];
            $finance_data['relation_user_num'] = $order_info['user_sn'];
            $finance_data['entry'] = 1;
            $finance_data['money'] = $order_data['pay_price'];
            $finance_data['content'] = '用户购买商品进行支付';
            $finance_data['pay_type'] = 5;
            $finance_data['act'] = 1;
            $financeServices->syncFinance($finance_data);
            $content .="========================处理成功============================";
            echo $str;
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $content .= '---------'.$e->getMessage()."--------------------\n";
        }
        createLog($path, $content);
    }
    /**
     * @xk 子订单支付回调
     * @method                            wechatSubOrderPayBack
     * @return                            [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                   <zhonghuaxinxing@sina.cn>
     * @City：                             青岛
     * @Time：2022-02-10Tfalse15:04:07+080
     */
    public static function wechatSubOrderPayBack()
    {
        $subOrderModel = new SubOrderModel();
        $orderServices = new OrderServices();
        $financeServices = new FinanceServices();
        Db::startTrans();
        $param = request()->param();
        $path = 'wechatPay/orderPay/';
        $content = "---------------【接收订单回调】---------------------------\n";
        try {
            $result = file_get_contents('php://input');
            $data = self::getxml($result); //开始处理微信回调
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            if ('SUCCESS' != $data['result_code']) {
                throw new \think\Exception($result, 404);
            }
            $content .= '----------------------订单编号----'.$data['out_trade_no']."------------------------\n";
            $pay_order_sn = $data['out_trade_no'];
            $order_info = $subOrderModel->where([['pay_order_sn','=',$pay_order_sn]])->field('`sub_order_sn`,`user_sn`,`status`,`pay_status`,`shipping_type`,`sub_order_id`')->find();
            if (!$order_info) {
                throw new \think\Exception("订单不存在", 404);
            }
            if ($order_info['pay_status'] != 0) {
                throw new \think\Exception("订单状态错误", 404);
            }
            $order_data = [];
            $shipping_type = $order_info['shipping_type'];
            $order_data['status'] = 1;
            if ($shipping_type == 2) {
                $order_data['status'] = 2; //
              $order_data['delivery_time'] = date('Y-m-d H:i:s'); // 自提订单记录发货时间
            }
            $order_data['pay_status'] = 1;
            $order_data['sub_order_id'] = $order_info['sub_order_id'];
            $order_data['pay_time'] = date('Y-m-d H:i:s'); // 支付时间
            $order_data['pay_type'] = 5;
            $order_data['pay_price'] = $data['total_fee']/100; // 支付金额
            $order_data['pay_code'] = $data['transaction_id']; // 支付流水号
            $order_res = $subOrderModel->find($order_info['sub_order_id'])->save($order_data);
            $orderServices->syncOrderGoodsStatus($order_info['sub_order_sn']);
            $finance_data = [];
            $finance_data['relation_num'] = $order_info['sub_order_sn'];
            $finance_data['relation_user_num'] = $order_info['user_sn'];
            $finance_data['entry'] = 1;
            $finance_data['money'] = $order_data['pay_price'];
            $finance_data['content'] = '用户购买商品进行支付';
            $finance_data['pay_type'] = 1;
            $finance_data['act'] = 2;
            $financeServices->syncFinance($finance_data);
            echo $str;
            $content .="========================处理成功============================\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .="===========================".$e->getMessage()."==========================\n";
            Db::rollback();
        };
        createLog($path, $content);
    }
    /**
     * @xk 执行订单退款操作
     *
     * @method orderRefundPay
     * @return [type]         [description]
     * @Time   2021-11-03
     * @City   青岛
     * @Author xkyinzhe       <zhonghuaxinxing@sina.cn>
     */
    public static function orderRefundPay($data=[])
    {
        $refundOrderModel = new RefundOrderModel();
        $subOrderModel = new SubOrderModel();
        $orderServices = new OrderServices();
        $financeServices = new FinanceServices();
        $post_data = [];
        $post_data['msgSrc'] = config('web_config.msgSrc');
        $post_data['msgType'] = 'refund';
        $post_data['merOrderId'] = $data['pay_order_sn'];
        $post_data['mid'] = config('web_config.mid');
        $post_data['tid'] = config('web_config.tid');
        $post_data['requestTimestamp'] = date('Y-m-d H:i:s');
        $post_data['msgId'] = $data['refund_order_sn'];
        $post_data['signType'] = 'SHA256';
        $post_data['refundAmount'] = $data['refund_check_price']*100;
        $post_data['sign'] = self::makeSign($post_data, config('web_config.unionpayscript'));
        $url = 'https://qr.chinaums.com/netpay-route-server/api/';
        $result = self::https_request($url, json_encode($post_data));
        $result = json_decode($result, true);
        // 判断退款是否成功
        if (!$result) {
            throw new \think\Exception("退款接口异常，请联系管理员处理", 404);
        }
        if ($result['errCode'] != 'SUCCESS') {
            throw new \think\Exception($result['errMsg'], 404);
        }
        if ($result['status'] != 'TRADE_SUCCESS') {
            throw new \think\Exception("当前交易还未支付完成，请重新发起", 404);
        }
        if ($result['refundStatus'] != 'SUCCESS') {
            throw new \think\Exception($result['errMsg'], 404);
        }
        // 退款成功 开始写入退款流水
        $finance_data = [];
        $finance_data['relation_num'] = $data['refund_order_sn']; // 售后订单编号
        $finance_data['relation_user_num'] = $data['user_sn'];
        $finance_data['entry'] = 2; // 平台出账
        $finance_data['money'] = $data['refund_check_price'];
        // $finance_data['money'] = $result['totalAmount']/100;
        $finance_data['content'] = '用户进行退款，平台支出';
        $finance_data['pay_type'] = 1;
        $finance_data['act'] = 4; // 申请退款
        $financeServices->syncFinance($finance_data);
        // 开始写入订单状态
        $order_data = [];
        $order_data['refund_price'] = $data['refund_check_price'];
        // $order_data['refund_price'] = $result['totalAmount']/100;
        // $order_data['refund_code'] = date('YmdHis').round(1111111,999999999);
        $order_data['refund_code'] = $result['refundOrderId'];
        $order_data['finish_time'] = date('Y-m-d H:i:s');
        // 开始执行 相关操作
        $order_data['status'] = 1.3; // 退款完成
        if ($data['type'] == 2) {
            $order_data['status'] = 2.5; // 退货完成
        }
        $refund_order_res = $refundOrderModel->where([['refund_order_sn','=',$data['refund_order_sn']]])->save($order_data);
        // 写入平台流水记录
        $orderServices->syncRefundResult($data['refund_order_sn']);
        return true;
    }
    /**
     * @xk 执行微信退款
     * @method                                      wechatOrderRefundPay
     * @param                                       array $data  [description]
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-02-10Tfalse15:false15:false55+080
     */
    public static function wechatOrderRefundPay($data=[])
    {
        $push = [];
        // 执行退款
        $notify_url = 'https://'.$_SERVER['HTTP_HOST'].'/common/Unionpay/orderRefundPayBack';
        $push['appid'] = config('wechat_config.wechat_app_id');
        $push['mch_id'] = config('wechat_config.wechat_mch_id');
        $push['nonce_str'] = self::nocestr();
        $push['out_refund_no'] = $data['refund_order_sn'];
        $push['transaction_id'] = $data['pay_code'];
        $push['notify_url'] = $notify_url;
        $push['total_fee'] = $data['pay_price']*100; //总金额 最低为一块钱 必须是整数
        $push['refund_fee'] = $data['refund_check_price']*100; //总金额 最低为一块钱 必须是整数
        $push['sign'] = self::wechatMakeSign($push, config('wechat_config.wecaht_mch_script')); //签名
        $post_xml = self::toXml($push);
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
        $xml = self::postXmlSSLCurl($post_xml, $url); //调用统一下单接口
        $path = 'wechatPay/orderRefundPay/';
        $content = "---【".$data['refund_order_sn']."】-----接收退款操作开始--------\n";
        $content .= $post_xml."\n";
        createLog($path, $content);
        // 处理返回数据
        $array = [];
        if ($xml) {
            $array = self::getxml($xml); //全要大写
        }
        if ($array) {
            if ('SUCCESS' != $array['return_code'] || 'SUCCESS' != $array['result_code']) {
                throw new \think\Exception($array['return_msg'], 1);
            }
        }
        return true;
    }
    /**
     * @xk 原生微信支付退款回调
     * @method                                      orderRefundPayBack
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-02-10Tfalse15:false23:false17+080
     */
    public static function orderRefundPayBack()
    {
        $refundOrderModel = new RefundOrderModel();
        $subOrderModel = new SubOrderModel();
        $orderServices = new OrderServices();
        $financeServices = new FinanceServices();
        Db::startTrans();
        $path = 'wechatPay/Refound/';
        $content = "---------------【接收订单回调】---------------------------\n";
        try {
            $result = file_get_contents('php://input');
            $data = self::getxml($result); //开始处理微信回调
            if ('SUCCESS' != $data['return_code']) {
                throw new \think\Exception($result, 404);
            }
            $req_info = $data['req_info'];
            $base_req_info = base64_decode($req_info, true);
            $key_md5 = md5(config('wechat_config.wecaht_mch_script'));
            // 开始执行解密操作
            $refound_info = openssl_decrypt($base_req_info, 'aes-256-ecb', $key_md5, OPENSSL_RAW_DATA);
            $refound_info_arr = self::getxml($refound_info);
            $content .= "--------------【".$refound_info_arr['out_trade_no']."】--退款单号（支付单号）----------------\n";
            $refund_order_sn = $refound_info_arr['out_refund_no'];
            $refund_infox = $refundOrderModel
                        ->where(['refund_order_sn' => $refund_order_sn])
                        ->field('`refund_order_sn`,`sub_order_sn`,`user_sn`,`status`,`refund_check_price`,`type`')
                        ->find();
            if (!$refund_infox) {
                throw new \think\Exception('【'.$data['out_refund_no'].'】订单信息不存在', 404);
            }
            $refund_infox = $refund_infox->toArray();
            if (1.1 != $refund_infox['status'] && $refund_infox['status'] != 2.4) {
                throw new \think\Exception('【订单进入其他状态】', 404);
            }
            // 退款成功 开始写入退款流水
            $finance_data = [];
            $finance_data['relation_num'] = $refund_order_sn; // 售后订单编号
            $finance_data['relation_user_num'] = $refund_infox['user_sn'];
            $finance_data['entry'] = 2; // 平台出账
            $finance_data['money'] = $refund_infox['refund_check_price'];
            $finance_data['content'] = '用户进行退款，平台支出';
            $finance_data['pay_type'] = 5;
            $finance_data['act'] = 4; // 申请退款
            $financeServices->syncFinance($finance_data);
            // 开始写入订单状态
            $order_data = [];
            $order_data['refund_price'] = $refund_infox['refund_check_price'];
            $order_data['refund_code'] = $refound_info_arr['transaction_id'];
            $order_data['finish_time'] = date('Y-m-d H:i:s');
            // 开始执行 相关操作
            $order_data['status'] = 1.3; // 退款完成
            if ($refund_infox['type'] == 2) {
                $order_data['status'] = 2.5; // 退货完成
            }
            $refund_order_res = $refundOrderModel->where([['refund_order_sn','=',$refund_infox['refund_order_sn']]])->save($order_data);
            // 写入平台流水记录
            $orderServices->syncRefundResult($refund_infox['refund_order_sn']);
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            echo $str;
            $content .= "------------------------------处理成功---------------------------------------------\n";
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $content .= '---------'.$e->getMessage()."--------------------\n";
        }
        createLog($path, $content);
    }
    /**
     * @xk 组合ASI
     *
     * @method signTemp
     * @param  [type]     $data                      [description]
     * @return [type]     [description]
     * @Time   2021-10-22
     * @City   青岛
     * @Author xkyinzhe   <zhonghuaxinxing@sina.cn>
     */
    public static function signTemp($data)
    {
        ksort($data);
        $stringA = '';
        foreach ($data as $key => $value) {
            if (!$value) {
                continue;
            }
            if ($stringA) {
                $stringA .= '&'.$key.'='.urlencode((string)$value);
            } else {
                $stringA = $key.'='.urlencode((string)$value);
            }
        }
        return $stringA;
    }
    /**
     * @xk 生成签名
     *
     * @method createSign
     * @param  [type]     $data                      [description]
     * @return [type]     [description]
     * @Time   2021-10-22
     * @City   青岛
     * @Author xkyinzhe   <zhonghuaxinxing@sina.cn>
     */
    public static function makeSign($data, $keyscript)
    {
        ksort($data);
        $stringA = '';
        foreach ($data as $key => $value) {
            if (!$value) {
                continue;
            }
            if ($stringA) {
                $stringA .= '&'.$key.'='.$value;
            } else {
                $stringA = $key.'='.$value;
            }
        }
        //申请支付后有给予一个商户账号和密码，登陆后自己设置key
           $stringSignTemp = $stringA.$keyscript; //申请支付后有给予一个商户账号和密码，登陆后自己设置key
           $sign = hash("sha256", $stringSignTemp);
        return strtoupper($sign);
    }
    /**
     * @xk 微信支付签名加密
     * @method                                      wechatMakeSign
     * @param                                       [type] $data  [description]
     * @param                                       [type] $keyscript  [description]
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-02-10Tfalse14:false55:false32+080
     */
    public static function wechatMakeSign($data, $keyscript)
    {
        ksort($data);
        $stringA = '';
        foreach ($data as $key => $value) {
            if (!$value) {
                continue;
            }
            if ($stringA) {
                $stringA .= '&'.$key.'='.$value;
            } else {
                $stringA = $key.'='.$value;
            }
        }
        //申请支付后有给予一个商户账号和密码，登陆后自己设置key
            $stringSignTemp = $stringA.'&key='.$keyscript; //申请支付后有给予一个商户账号和密码，登陆后自己设置key
            $sign = md5($stringSignTemp); //注：MD5签名方式
            return $sign;
    }
    /**
     * @xk 生成随机字符串
     *
     * @method   nocestr
     * @Version： V2.0
     * @Author   xkyinzhe
     * @Time     2020-10-26T15:26:06+080
     *
     * @return [type] [description]
     */
    public static function nocestr()
    {
        $result = '';
        $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
        for ($i = 0; $i < 32; ++$i) {
            $result .= $str[rand(0, 48)];
        }

        return $result;
    }
    /**
     * @xk 生成XML
     *
     * @method   toXml
     * @Version： V2.0
     * @Author   xkyinzhe
     * @Time     2020-10-26T15:28:01+080
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     */
    public static function toXml($data)
    {
        if (!is_array($data) || count($data) <= 0) {
            throw new WxPayException('数组数据异常！');
        }
        $xml = '<xml>';
        foreach ($data as $key => $val) {
            if (is_numeric($val)) {
                $xml .= '<'.$key.'>'.$val.'</'.$key.'>';
            } else {
                $xml .= '<'.$key.'><![CDATA['.$val.']]></'.$key.'>';
            }
        }
        $xml .= '</xml>';

        return $xml;
    }

    /**
     * @xk 解析XML
     *
     * @method   Getxml
     * @Version： V2.0
     * @Author   xkyinzhe
     * @Time     2020-10-26T15:28:24+080
     *
     * @param [type] $xml [description]
     */
    public static function Getxml($xml)
    {
        // libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

        return $values;
    }
    /**
     * @xk 带证书 curl
     *
     * @method   postXmlSSLCurl
     * @Version： V2.0
     * @Author   xkyinzhe
     * @Time     2020-10-26T15:28:55+080
     *
     * @param [type] $xml    [description]
     * @param [type] $url    [description]
     * @param int    $second [description]
     *
     * @return [type] [description]
     */
    public static function postXmlSSLCurl($xml, $url, $second = 30)
    {
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, false);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        //默认格式为PEM，可以注释
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT, __DIR__.'/../../../public/cert/apiclient_cert.pem');
        //默认格式为PEM，可以注释
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, __DIR__.'/../../../public/cert/apiclient_key.pem');
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $data = curl_exec($ch);

        //返回结果
        if ($data) {
            curl_close($ch);

            return $data;
        } else {
            $error = curl_errno($ch);
            $path = 'pay/curlError/';
            $content = json_encode(curl_getinfo($ch))."\n";
            $content .= __DIR__."/../../../public/cert/apiclient_key.pem--\n";
            createLog($path, $content);
            // echo "curl出错，错误码:$error".'<br>';
            // echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
            curl_close($ch);

            return false;
        }
    }
    /**
     * @xk CURL请求
     *
     * @method https_request
     * @param  [type]        $url                       [description]
     * @param  [type]        $data                      [description]
     * @param  array         $headers                   [description]
     * @return [type]        [description]
     * @Time   2021-10-22
     * @City   青岛
     * @Author xkyinzhe      <zhonghuaxinxing@sina.cn>
     */
    public static function https_request($url, $data = null, $headers = ["Content-type: application/json;charset='utf-8'"])
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        // echo '第三方返回的错误是: ' . curl_error($curl);
        // dump($output);die();
        curl_close($curl);

        return $output;
    }
}
